import re

# 先编译好正则
re_email = re.compile(r'^[\w]+\.?[\w]+@[\w]+\.com$')
# 正则解释：     字母一个以上 .一个或没有 字母一个以上 @ 字母不限 .com


def is_valid_email(addr):
    if re_email.match(addr):
        return True


# 测试:
assert is_valid_email('someone@gmail.com')
assert is_valid_email('bill.gates@microsoft.com')
assert not is_valid_email('bob#example.com')
assert not is_valid_email('mr-bob@example.com')
print('ok')

print('======================================================================')

re_name_of_email = re.compile(r'^<?([\w]+\s*[\w]*)>?\s*[\w]*@[\w]+\.org$')
# 正则解释    <一个或无 字母一个以上 空格不限 字母不限 >一个或无 @ 字母一个以上 .org


def name_of_email(addr):
    if re_name_of_email.match(addr):
        return re_name_of_email.match(addr).group(1)


# 测试:
assert name_of_email('<Tom Paris> tom@voyager.org') == 'Tom Paris'
assert name_of_email('tom@voyager.org') == 'tom'
print('ok')

print('======================================================================')
import base64


def safe_base64_decode(s):

    # 判断是否是4的整数u，不够的在末尾添加等号
    if len(s) % 4 != 0:
        s = s + bytes('=', encoding='utf-8') * (4 - len(s) % 4)

    # 解决字符串和bytes类型
    if not isinstance(s, bytes):
        s = bytes(s, encoding='utf-8')

    # 解码 
    base64_str = base64.b64decode(s)

    return base64_str


# 测试:
assert b'abcd' == safe_base64_decode(b'YWJjZA=='), safe_base64_decode('YWJjZA==')
assert b'abcd' == safe_base64_decode(b'YWJjZA'), safe_base64_decode('YWJjZA')
print('ok')

print('======================================================================')
# -*- coding: utf-8 -*-
import base64, struct
bmp_data = base64.b64decode('Qk1oAgAAAAAAADYAAAAoAAAAHAAAAAoAAAABABAAAAAAADICAAASCwAAEgsAA' +
                   'AAAAAAAAAAA/3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3/' +
                   '/f/9//3//f/9//3//f/9/AHwAfAB8AHwAfAB8AHwAfP9//3//fwB8AHwAfAB8/3//f/9/A' +
                   'HwAfAB8AHz/f/9//3//f/9//38AfAB8AHwAfAB8AHwAfAB8AHz/f/9//38AfAB8/3//f/9' +
                   '//3//fwB8AHz/f/9//3//f/9//3//f/9/AHwAfP9//3//f/9/AHwAfP9//3//fwB8AHz/f' +
                   '/9//3//f/9/AHwAfP9//3//f/9//3//f/9//38AfAB8AHwAfAB8AHwAfP9//3//f/9/AHw' +
                   'AfP9//3//f/9//38AfAB8/3//f/9//3//f/9//3//fwB8AHwAfAB8AHwAfAB8/3//f/9//' +
                   '38AfAB8/3//f/9//3//fwB8AHz/f/9//3//f/9//3//f/9/AHwAfP9//3//f/9/AHwAfP9' +
                   '//3//fwB8AHz/f/9/AHz/f/9/AHwAfP9//38AfP9//3//f/9/AHwAfAB8AHwAfAB8AHwAf' +
                   'AB8/3//f/9/AHwAfP9//38AfAB8AHwAfAB8AHwAfAB8/3//f/9//38AfAB8AHwAfAB8AHw' +
                   'AfAB8/3//f/9/AHwAfAB8AHz/fwB8AHwAfAB8AHwAfAB8AHz/f/9//3//f/9//3//f/9//' +
                   '3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//3//f/9//38AAA==')

def bmp_info(data):
    info = struct.unpack('<ccIIIIIIHH', data[:30])
    # struct.unpack 如果不明白的可以在廖雪峰老师的python课程中仔细看看，通俗理解就是将二进制数据解析出来
    if info[0] == b'B' and (info[1] == b'M' or info[1] == b'A'):
        # 这里是做相应的判断，判断是否为位图
        return {
            'width': info[6],
            'height': info[7],
            'color': info[9]
        }
# 测试
bi = bmp_info(bmp_data)
assert bi['width'] == 28
assert bi['height'] == 10
assert bi['color'] == 16
print('ok')
print('======================================================================')
# -*- coding: utf-8 -*-
import hashlib, random

def get_md5(s):
    return hashlib.md5(s.encode('utf-8')).hexdigest()#生成MD5值

class User(object):
    def __init__(self, username, password):
        self.username = username
        # 生成盐。randint()生成范围内的随机整数。chr()，生成整数对应的ASCII码字符。for 循环20次
        self.salt = ''.join([chr(random.randint(48, 122)) for i in range(20)])
        self.password = get_md5(password + self.salt)
db = {
    'michael': User('michael', '123456'),
    'bob': User('bob', 'abc999'),
    'alice': User('alice', 'alice2008')
}

def login(username, password):
    user = db[username]
    return user.password == get_md5(password+user.salt)

# 测试:
assert login('michael', '123456')
assert login('bob', 'abc999')
assert login('alice', 'alice2008')
assert not login('michael', '1234567')
assert not login('bob', '123456')
assert not login('alice', 'Alice2008')
print('ok')
print('======================================================================')
# -*- coding: utf-8 -*-
# 计算圆周率可以根据公式：
# 利用Python提供的itertools模块，我们来计算这个序列的前N项和：
import itertools


def pi(N):
    '计算pi的值'
        #     step1 创建一个奇数序列:
    s1 = itertools.count(start=1, step=2)
        #     step2 取该序列的前N项：
    s2 = list(itertools.takewhile(lambda x: x < 2 * N - 1, s1))
        # print(list(s2))
        #    step3 添加正负符号并用4除：4/1.-4/3.4/5，-4/7，4/9
    l = len(s2)
    s3 = (4 * pow(-1, x) for x in list(range(l)))
        # print(s3)
    result = 0
    count=0
    #  s3 = [4 * pow(-1, x) for x in list(range(l))]
        # for i in range(l):
        #     result += s3[i] / s2[i]
    for i in s3:
            # print(i)
        result += i/s2[count]
        count += 1
    return result

# 测试:
print(pi(10))
print(pi(100))
print(pi(1000))
print(pi(10000))
print('ok')
print('======================================================================')
from urllib import request

with request.urlopen('https://unsplash.com/s/photos/picture') as f:
    data = f.read()
    print('Status:', f.status, f.reason)
    for k, v in f.getheaders():
        print('%s: %s' % (k, v))
    #print('Data:', data.decode('utf-8'))
print('======================================================================')
"""#1、利用urllib读取JSON，然后将JSON解析为Python对象：

# -*- coding: utf-8 -*-
from urllib import request
import json
def fetch_data(url):
    with request.urlopen(url) as f:
        data = json.loads(f.read().decode('utf-8')) #将读到的网页内容解码，再由json.loads()反序列化为Python对象
    return data

# 测试
URL = 'https://www.picture-organic-clothing.com/en/'
data = fetch_data(URL)
print(data)
assert data['query']['results']['channel']['location']['city'] == 'Beijing'
print('ok')"""